// fast4j - Fast & Agile Service Tools for Java
// Copyright (C) 2007 Alexandre ROMAN
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

// $Id: AbstractApplicationCreator.java 51 2007-04-08 12:37:12Z alexandre.roman $

package fast4j.ace.impl;

import java.io.File;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fast4j.ace.ApplicationCreationFailedException;
import fast4j.ace.ApplicationCreator;
import fast4j.ace.ApplicationDescriptor;
import fast4j.ace.PropertyDescriptor;

/**
 * Base {@link ApplicationCreator} implementation.
 * @author alexandre.roman
 */
public abstract class AbstractApplicationCreator implements ApplicationCreator {
    /**
     * Log facility.
     */
    protected final Logger log = LoggerFactory.getLogger(getClass());
    /**
     * Supported properties.
     */
    protected final Set<PropertyDescriptor> supportedProperties = new HashSet<PropertyDescriptor>();
    
    public final Set<PropertyDescriptor> getSupportedProperties() {
        return Collections.unmodifiableSet(supportedProperties);
    }
    
    public final void create(ApplicationDescriptor desc, File dir)
            throws ApplicationCreationFailedException {
        if (desc == null) {
            throw new IllegalArgumentException(
                    "ApplicationDescriptor is required and cannot be null");
        }
        if (dir == null) {
            throw new IllegalArgumentException(
                    "Output directory is required and cannot be null");
        }
        
        final long start = System.currentTimeMillis();
        log.info("Creating application: {}", desc.getName());
        try {
            doCreate(desc, dir);
        } catch (Exception e) {
            throw new ApplicationCreationFailedException(
                    "Failed to create application: " + e.getMessage(), e);
        }
        final long timeMillis = System.currentTimeMillis() - start;
        log.info("Application created in {} second(s)", new BigDecimal(
                timeMillis / 1000d, new MathContext(2)));
    }
    
    /**
     * Create an application. This method is called from
     * {@link #create(ApplicationDescriptor, File)}, and should be implemented
     * by subclasses.
     */
    protected abstract void doCreate(ApplicationDescriptor desc, File dir)
            throws Exception;
}
